﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Publicuse.Util
{
    public class LogUtil
    {
        private static LogUtil instance;

        private static readonly object loglock = new object();

        static LogUtil()
        {
            instance = new LogUtil();
        }

        public static LogUtil GetInstance
        {
            get { return instance; }
        }

        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="modulename"></param>
        /// <returns></returns>
        private string CreateDirectory(string initmodule, string modulename)
        {
            modulename = modulename.Replace("-", "\\");
            var newpath = initmodule + modulename;
            newpath = newpath.Replace("\\", "/"); // Linux系统部署路径需要改成这样
            DirectoryInfo directoryInfo = new DirectoryInfo(newpath);
            directoryInfo.Create();
            return newpath;
        }

        public void WriteLogOld(string module, string content, bool isSuccess)
        {
            var timepath = AppDomain.CurrentDomain.BaseDirectory + "Logs\\" + DateTime.Now.ToString("yyyyMMdd");
            timepath = timepath.Replace("\\", "/"); // Linux系统部署路径需要改成这样
            if (!Directory.Exists(timepath))
            {
                Directory.CreateDirectory(timepath);
                WriteLogOld(module, content, isSuccess);
            }
            else
            {
                var filepath = CreateDirectory(timepath + "\\", module);
                filepath = filepath.Replace("\\", "/"); // Linux系统部署路径需要改成这样
                if (!string.IsNullOrEmpty(content))
                {
                    var filetime = isSuccess == true ? "成功" : "失败";
                    var newfilepath = filepath + "\\" + filetime + ".txt";
                    newfilepath = newfilepath.Replace("\\", "/"); // Linux系统部署路径需要改成这样
                    content = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  " + content;
                    WriteLog(newfilepath, content, isSuccess);
                }
            }
        }

        /// <summary>  
        /// 写入文本  
        /// </summary>  
        /// <param name="content">文本内容</param>  
        private static void Write(string content, string path, bool newLine)
        {
            using (StreamWriter fs = new StreamWriter(path, newLine, Encoding.UTF8))
            {
                fs.WriteLineAsync(content);
            }
        }

        public delegate void WriteLogDelegate(string path, string content, bool newLine);

        private void WriteLog(string path, string content, bool newLine)
        {
            //WriteLogDelegate wLog = WriteContentToFile;
            //wLog.BeginInvoke(path, content, newLine, null, null);
            Task.Run(() =>
            {
                WriteContentToFile(path, content, newLine);
            });
        }

        /// <summary>
        /// 写入内容到文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="content"></param>
        private static void WriteContentToFile(string path, string content, bool newLine)
        {
            lock (loglock)
            {
                try
                {
                    Encoding encode = Encoding.UTF8;
                    if (File.Exists(path))
                    {
                        var olddatalength = ReadFileLines(path);
                        if (olddatalength == 0)//文件没有存在内容
                        {
                            using (var file = new FileStream(path, FileMode.OpenOrCreate))
                            {
                                byte[] data = encode.GetBytes(content);
                                file.Write(data, 0, data.Length);
                            }
                        }
                        else//追加内容到原有文件
                        {
                            using (var file = new FileInfo(path).AppendText())
                            {
                                if (newLine)
                                {
                                    if (olddatalength == 1)
                                        file.WriteLine("");

                                    file.WriteLine("");
                                    file.WriteLine(content);
                                }
                                else
                                {
                                    file.Write(content);
                                }
                            }
                        }
                    }
                    else//创建新文件并写入内容
                    {
                        using (var file = new FileStream(path, FileMode.OpenOrCreate))
                        {
                            byte[] data = encode.GetBytes(content);
                            file.Write(data, 0, data.Length);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogUtil.GetInstance.WriteLogOld("异常", path + content + "|" + ex.Message + ex.InnerException + ex.StackTrace, false);
                }
            }
        }

        /// <summary>
        /// 读取文件内容长度
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private static int ReadFileLines(string path)
        {
            using (var stream = new StreamReader(path, Encoding.UTF8))
            {
                string con = stream.ReadToEnd();
                return con.Length;
            }
        }
    }

    public class TraceHelper
    {
        private static TraceHelper _traceHelper;

        private TraceHelper() { }

        public static TraceHelper GetInstance()
        {
            if (_traceHelper == null)
                _traceHelper = new TraceHelper();

            return _traceHelper;
        }

        public void Error(string message, string module)
        {
            this.Log(message, MessageType.Error, module);
        }

        public void Error(Exception ex, string module)
        {
            this.Log(ex.StackTrace, MessageType.Error, module);
        }

        public void Warning(string message, string module)
        {
            this.Log(message, MessageType.Warning, module);
        }

        public void Info(string message, string module)
        {
            this.Log(message, MessageType.Information, module);
        }

        public void Log(string message, MessageType type, string module)
        {
            Trace.WriteLine(
                string.Format("{0},{1},{2},{3}",
                DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                type.ToString(),
                module,
                message));
        }
    }


    public enum MessageType
    {
        Information = 0,
        Warning = 1,
        Error = 2
    }

    public enum LogModuleType : int
    {
        Wateronsale = 0,
        Bus = 1,
        DB = 2
    }
    public class LogClass
    {
        public string ModuleName { get; set; }

        public string ModuleAction { get; set; }

        public string SpadminName { get; set; }

        public string IpAddress { get; set; }

        public DateTime CreateTime { get; set; }

        public int IsPassSuccess { get; set; }

        public string SystemRemark { get; set; }

        public string Exception { get; set; }


        public LogClass()
        {
            this.CreateTime = DateTime.Now;
            this.IpAddress = GetIPAddress() + "|" + GetClientLocalIPv4Address();
            this.SystemRemark = GetSystemName() + "|" + GetSystemType();
            this.IsPassSuccess = 0;
        }

        public static string sql(string ModuleName, string ModuleAction, bool IsPassSuccess, string Exception, string user = "spadmin")
        {
            LogClass lc = new LogClass()
            {
                ModuleName = ModuleName,
                IsPassSuccess = IsPassSuccess ? 1 : 0,
                Exception = Exception,
                SpadminName = user,
                ModuleAction = ModuleAction
            };
            string sql = string.Format("insert into sys_log (ModuleName,ModuleAction,SpadminName,IpAddress,CreateTime,IsPassSuccess,SystemRemark, Exception) values ('{0}','{1}','{2}','{3}','{4}',{5},'{6}','{7}')",
                lc.ModuleName, lc.ModuleAction, lc.SpadminName, lc.IpAddress, lc.CreateTime, lc.IsPassSuccess, lc.SystemRemark, lc.Exception);
            return sql;
        }

        /// <summary>  
        /// 获取客户端内网IPv4地址  
        /// </summary>  
        /// <returns>客户端内网IPv4地址</returns>  
        public static string GetClientLocalIPv4Address()
        {
            string strLocalIP = string.Empty;
            try
            {
                IPHostEntry ipHost = Dns.Resolve(Dns.GetHostName());
                IPAddress ipAddress = ipHost.AddressList[0];
                strLocalIP = ipAddress.ToString();
                return strLocalIP;
            }
            catch
            {
                return "unknown";
            }
        }

        public static string GetIPAddress()
        {
            try
            {
                //获取IP地址   
                string st = "";
                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    if ((bool)mo["IPEnabled"] == true)
                    {
                        //st=mo["IpAddress"].ToString();   
                        System.Array ar;
                        ar = (System.Array)(mo.Properties["IpAddress"].Value);
                        st = ar.GetValue(0).ToString();
                        break;
                    }
                }
                moc = null;
                mc = null;
                return st;
            }
            catch
            {
                return "unknow";
            }
            finally
            {
            }

        }

        /// <summary>  
        /// 获取本机MAC地址  
        /// </summary>  
        /// <returns>本机MAC地址</returns>  
        public static string GetMacAddress()
        {
            try
            {
                string strMac = string.Empty;
                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    if ((bool)mo["IPEnabled"] == true)
                    {
                        strMac = mo["MacAddress"].ToString();
                    }
                }
                moc = null;
                mc = null;
                return strMac;
            }
            catch
            {
                return "unknown";
            }
        }

        /// <summary>  
        /// 获取操作系统类型  
        /// </summary>  
        /// <returns>操作系统类型</returns>  
        public static string GetSystemType()
        {
            try
            {
                string strSystemType = string.Empty;
                ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    strSystemType = mo["SystemType"].ToString();
                }
                moc = null;
                mc = null;
                return strSystemType;
            }
            catch
            {
                return "unknown";
            }
        }


        /// <summary>  
        /// 获取操作系统名称  
        /// </summary>  
        /// <returns>操作系统名称</returns>  
        public static string GetSystemName()
        {
            try
            {
                string strSystemName = string.Empty;
                ManagementObjectSearcher mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT PartComponent FROM Win32_SystemOperatingSystem");
                foreach (ManagementObject mo in mos.Get())
                {
                    strSystemName = mo["PartComponent"].ToString();
                }
                mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT Caption FROM Win32_OperatingSystem");
                foreach (ManagementObject mo in mos.Get())
                {
                    strSystemName = mo["Caption"].ToString();
                }
                return strSystemName;
            }
            catch
            {
                return "unknown";
            }
        }
    }
}
